<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入lodash库 -->
    <!-- <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script> -->

</head>

<body>
    <!-- 性能优化 -->
    <!-- <div id="box">
    </div> -->
    <!-- 防抖节流 -->
    <!-- <button id="btn">
        按钮按钮按钮按钮按钮
    </button> -->
</body>
<script>
    // ===========================================================================
    // Html性能优化
    // 1.控制DOM层级，减少额外标签使用。能用一层就不要写成两层



    // ---------------------------------------------------------------------------
    // 2.页面渲染和修改本质上是修改标签的属性，而每个标签的属性默认就有300+个
    // 所以频繁操作DOM本质上是操作这些属性，这样是非常小号性能的。在实际项目中尽量减少频繁操作DOM



    // --------------------------------------------------------------------------
    // 3.减少重绘和回流
    // 面试题：说一说重绘和回流？哪些操作会触发重绘，那些操作会触发回流
    // 重绘：改变元素的颜色、透明度等信息
    // 回流/重排：改变元素的尺寸、位置等几何属性
    // 结论：回流一定会触发重绘，重绘不一定会触发回流



    // --------------------------------------------------------------------------
    // 4.使用innerHTML代替DOM操作
    // 笔试题：请问下面代码有什么性能问题？如何解决？
    // var box = document.querySelector('#box');
    // for (let index = 0; index < 100; index++) {
    //     var p = document.createElement('p');
    //     p.textContent = i;
    //     // 每次添加都会触发一次回流
    //     box.appendChild(p);
    // }
    // // 更改：
    // var str = ''
    // for (let index = 0; index < 100; index++) {
    //     str += '<p>' + index + '</p>'
    // }
    // // 这样操作只触发一次回流
    // box.innerHTML = str




    // ---------------------------------------------------------------------------
    // 5.避免使用css表达式
    // ---------------------------------------------------------------------------
    // 6.减少事件绑定，尽量使用事件委托
    // ---------------------------------------------------------------------------
    // 7.尽量使用css动画
    // ---------------------------------------------------------------------------
    // 8.适当使用Canvas
    // ---------------------------------------------------------------------------
    // 9.使用className代替大量的内联样式修改
    // ---------------------------------------------------------------------------
    // 10.避免通过javascript修复layout
    // ---------------------------------------------------------------------------
    // 11.减少iframe数量（iframe内容为空也消耗）
    // iframe可以当做一个小的浏览器
    // 优点：内部和外部数据是完全隔离的
    // 缺点：无法相互访问
    // 应用：项目中微前端早期就是用iframe实现



    // ===========================================================================
    // 防抖和节流

    // 没有做任何处理，每点击一次就调用一次函数
    // document.querySelector('#btn').addEventListener('click',function(){
    //     console.log('我被点击了');

    // })
    // ----------------------------------------------------------------------------------
    // 防抖：间隔指定时间内会执行代码，重复点击会重新计时
    // document.querySelector('#btn').addEventListener('click', debounce(function () {
    //     console.log('防抖处理后的请求');
    // }, 3000))
    // function debounce(fn, time) {
    //     var timer = null;
    //     return function () {
    //         // 已经执行了setTimeout，那么timer就是一个定时器的id
    //         if (timer) {
    //             clearTimeout(timer)
    //         }
    //         timer = setTimeout(function () {
    //             fn();
    //         }, time)
    //     }
    // }

    // document.querySelector('#btn').addEventListener('click', fd(fn, 500))
    // function fd(fn, time) {
    //     var timer = null;
    //     return function () {
    //         if (timer) {
    //             clearTimeout(timer);
    //         }
    //         timer = setTimeout(function () {
    //             fn();
    //         }, time)
    //     }

    // }
    // function fn() {
    //     console.log('防抖处理后的请求');
    // }

    // ------------------------------------------------------------------------------------
    // 节流：在指定时间间隔内只会执行一次代码
    // document.querySelector('#btn').addEventListener('click', throttle(function () {
    //     console.log('节流处理后的请求');
    // }, 3000))
    // function throttle(fn, time) {
    //     // 页面一加载就会执行
    //     var start = Date.now()
    //     return function () {
    //         // 点击按钮执行
    //         var end = Date.now();
    //         // 如果两次点击的时间间隔大于设定的间隔，就执行请求
    //         if (end - start > time) {
    //             fn();
    //             // 把当前点击时间保存为上次的时间 start
    //             start = Date.now()
    //         }
    //     }
    // }
    // -----------------------------------------------------------------------------------------------------------
    // 引入lodash库（第八行）
    // 检查是否引入成功
    // console.log(_);
    // 防抖_.debounce
    // document.querySelector('#btn').addEventListener('click', _.debounce(function () {
    //     console.log('防抖处理后的请求');
    // }, 3000))
    // 节流_.throttle
    // document.querySelector('#btn').addEventListener('click', _.throttle(function () {
    //     console.log('节流处理后的请求');
    // }, 3000))


</script>

</html>